package com.liyongjian.xhban.api;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.liyongjian.xhban.dal.AccountGroupDetailRepository;
import com.liyongjian.xhban.dal.AccountGroupFamilyRepository;
import com.liyongjian.xhban.dal.AccountGroupRepository;
import com.liyongjian.xhban.dal.BlogMediaRepository;
import com.liyongjian.xhban.dal.BlogRepository;
import com.liyongjian.xhban.dal.FeedbackRepository;
import com.liyongjian.xhban.dal.GroupRepository;
import com.liyongjian.xhban.dal.UserFriendRepository;
import com.liyongjian.xhban.dal.UserRepository;
import com.liyongjian.xhban.dto.AjaxResponse;
import com.liyongjian.xhban.dto.SessionUser;
import com.liyongjian.xhban.exception.XHBanException;
import com.liyongjian.xhban.model.AccountGroup;
import com.liyongjian.xhban.model.AccountGroupDetail;
import com.liyongjian.xhban.model.Blog;
import com.liyongjian.xhban.model.Feedback;
import com.liyongjian.xhban.model.Group;
import com.liyongjian.xhban.model.User;
import com.liyongjian.xhban.model.emumm.BlogType;
import com.liyongjian.xhban.model.emumm.LiveDieState;
import com.liyongjian.xhban.model.emumm.VerifyState;
import com.liyongjian.xhban.model.emumm.YesNoState;
import com.liyongjian.xhban.utils.MapUtils;


@Controller
@RequestMapping("/api/my")
public class MyController extends BaseController {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private AccountGroupRepository accountGroupRepository;
    @Autowired
    private GroupRepository groupRepository;
    @Autowired
    private AccountGroupDetailRepository accountGroupDetailRepository;
    @Autowired
    private BlogRepository blogRepository;
    @Autowired
    private BlogMediaRepository blogMediaRepository;
    @Autowired
    private UserFriendRepository userFriendRepository;
    @Autowired
    private AccountGroupFamilyRepository accountGroupFamilyRepository;



    @ResponseBody
    @RequestMapping(path = "group/list", method = RequestMethod.GET)
    public AjaxResponse list(HttpServletRequest request, String token, BlogType groupType,
            YesNoState isSealed, HttpServletResponse response) throws Exception {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getCurrentUser(token);
        List<AccountGroup> ags = accountGroupRepository.findByUserIdAndTypeAndState(su.getId(),
                groupType, LiveDieState.LIVE, isSealed);
        List<Map<String, Object>> lists = new ArrayList<Map<String, Object>>();
        for (AccountGroup ag : ags) {
            Group g = groupRepository.findOne(ag.groupId);
            Map<String, Object> map = MapUtils.convert(g);
            map.put("photo", userRepository.findOne(g.updUserId).photo);
            if (g.type == BlogType.HH) {
                map.put("money", ag.money);
                map.put("payMoney", ag.payMoney);

                if (g.updUserId.longValue() == su.id) {
                    List<AccountGroupDetail> agds = accountGroupDetailRepository
                            .findByGroupIdAndState(g.id, VerifyState.DQR);
                    List<Map<String, Object>> agdList = new ArrayList<Map<String, Object>>();
                    for (AccountGroupDetail agd : agds) {
                        Map<String, Object> agdMap = MapUtils.convert(agd);
                        User user = userRepository.findOne(agd.userId);
                        agdMap.put("photo", user.photo);
                        agdList.add(agdMap);
                    }
                    map.put("agds", agdList);
                }
            } else if (g.type == BlogType.JT) {
                map.put("sr", accountGroupFamilyRepository.sumSRByGroupId(g.id));
                map.put("zc", accountGroupFamilyRepository.sumZCByGroupId(g.id));
                map.put("jd", accountGroupFamilyRepository.sumJDByGroupId(g.id));
                map.put("fd", accountGroupFamilyRepository.sumFDByGroupId(g.id));
            }
            lists.add(map);
        }
        return ajax.setObj(lists);
    }

    @ResponseBody
    @RequestMapping(path = "group/detail", method = RequestMethod.GET)
    public AjaxResponse detail(HttpServletRequest request, String token, Long id,
            HttpServletResponse response) throws Exception {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getCurrentUser(token);
        Group g = groupRepository.findOne(id);
        Map<String, Object> map = MapUtils.convert(g);
        List<AccountGroup> ags = accountGroupRepository.findByGroupId(id);
        List<Map<String, Object>> userList = new ArrayList<Map<String, Object>>();
        for (AccountGroup ag : ags) {
            User user = userRepository.findOne(ag.userId);
            Map<String, Object> userMap = MapUtils.convert(user, "id", "name", "nickName", "photo");
            userMap.put("balance", new BigDecimal(ag.payMoney - ag.money)
                    .setScale(2, RoundingMode.UP).floatValue());
            userList.add(userMap);
        }
        map.put("userList", userList);
        return ajax.setObj(map);
    }


    @ResponseBody
    @RequestMapping(path = "group/upd", method = RequestMethod.POST)
    public AjaxResponse detail(HttpServletRequest request, String token, Long groupId, String name,
            YesNoState isSealed, String userIds, HttpServletResponse response) throws Exception {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getCurrentUser(token);
        if (!StringUtils.isEmpty(name)) {
            Group g = groupRepository.findOne(groupId);
            g.name = name;
            groupRepository.save(g);
        }
        if (isSealed != null) {
            Group g = groupRepository.findOne(groupId);
            g.isSealed = isSealed;
            groupRepository.save(g);
        }
        return ajax;
    }


    @ResponseBody
    @RequestMapping(path = "nick_name/upd", method = RequestMethod.POST)
    public AjaxResponse nick_name_upd(HttpServletRequest request, String token, String nickName)
            throws Exception {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getCurrentUser(token);
        User user = userRepository.findOne(su.id);
        user.nickName = nickName;
        userRepository.save(user);
        return ajax;
    }

    @ResponseBody
    @RequestMapping(path = "group/add", method = RequestMethod.POST)
    public AjaxResponse add(HttpServletRequest request, String name, String token,
            BlogType groupType) throws Exception {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getCurrentUser(token);
        int count = groupRepository.countByUpdUserIdAndTypeAndStateAndIsSealed(su.id, groupType,
                LiveDieState.LIVE, YesNoState.NO);
        if (count >= 5) {
            throw new XHBanException("最多可以用5个" + groupType.desc + "账单");
        }
        Group g = new Group();
        g.updUserId = su.id;
        g.name = name;
        g.userId = su.id;
        g.type = groupType;
        groupRepository.save(g);

        AccountGroup ag = new AccountGroup();
        ag.userId = g.userId;
        ag.groupId = g.id;
        accountGroupRepository.save(ag);
        return ajax;
    }

    @Transactional
    @ResponseBody
    @RequestMapping(path = "group/cancel/account", method = RequestMethod.POST)
    public AjaxResponse cancel(HttpServletRequest request, String token, Long blogId)
            throws Exception {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getCurrentUser(token);
        AccountGroupDetail agd = accountGroupDetailRepository.findByBlogId(blogId);
        if (agd.updUserId.longValue() != su.id) {
            throw new XHBanException("只有管理员才能取消账单");
        }
        if (agd.state == VerifyState.TG) {
            agd.state = VerifyState.BTG;
            accountGroupDetailRepository.save(agd);

            accountGroupRepository.updatePayMoneyByUserIdAndGroupId(agd.userId, agd.groupId,
                    -agd.money);
            String[] ids = StringUtils.strip(agd.userIds, ",").split(",");
            for (String userId : ids) {
                if (!StringUtils.isEmpty(userId)) {
                    accountGroupRepository.updateMoneyByUserIdAndGroupId(Long.valueOf(userId),
                            agd.groupId, -agd.userIdsMoney);
                }
            }
        }
        return ajax;
    }


    @ResponseBody
    @RequestMapping(path = "friend/list", method = RequestMethod.GET)
    public AjaxResponse my_list(HttpServletRequest request, String token,
            HttpServletResponse response) throws Exception {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getCurrentUser(token);
        List<User> users = userFriendRepository.findFriendByUserId(su.id);
        User user = userRepository.findOne(su.getId());
        users.add(0, user);
        return ajax.setObj(users);
    }


    @Transactional
    @ResponseBody
    @RequestMapping(path = "friend/add", method = RequestMethod.POST)
    public AjaxResponse friend_add(HttpServletRequest request, String token, Long[] userIds,
            Long groupId, HttpServletResponse response) throws Exception {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getCurrentUser(token);
        List<Long> users = accountGroupRepository.findUserIdByGroupId(groupId);
        for (Long id : userIds) {
            if (id != null && !users.contains(id)) {
                AccountGroup ag = new AccountGroup();
                ag.userId = id;
                ag.groupId = groupId;
                accountGroupRepository.save(ag);
            }
        }
        return ajax;
    }

    @ResponseBody
    @RequestMapping(path = "friend/del", method = RequestMethod.POST)
    public AjaxResponse friend_del(HttpServletRequest request, String token, Long userId,
            Long groupId, HttpServletResponse response) throws Exception {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getCurrentUser(token);
        Group g = groupRepository.findOne(groupId);
        if (g.updUserId != su.id.longValue()) {
            throw new XHBanException("没有移除权限");
        }
        AccountGroup ag = accountGroupRepository.findByUserIdAndGroupIdAndState(userId, groupId,
                LiveDieState.LIVE);
        ag.state = LiveDieState.DIE;
        accountGroupRepository.save(ag);
        return ajax;
    }

    @ResponseBody
    @RequestMapping(path = "group/blog", method = RequestMethod.GET)
    public AjaxResponse login(HttpServletRequest request, String token, Long groupId,
            BlogType groupType, HttpServletResponse response,
            @PageableDefault(sort = {"id"}, direction = Direction.DESC) Pageable pageable)
                    throws Exception {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getCurrentUser(token);
        Page<Blog> page = null;
        if (groupType == BlogType.HH) {
            page = blogRepository.pageByGroupId(groupId, pageable);
        } else if (groupType == BlogType.JT) {
            page = blogRepository.pagejtByGroupId(groupId, pageable);
        }
        return ajax.setObj(page.map(new Converter<Blog, Map<String, Object>>() {
            @Override
            public Map<String, Object> convert(Blog source) {
                Map<String, Object> map = MapUtils.convert(source);
                if (source.type == BlogType.HH) {
                    AccountGroupDetail agd = accountGroupDetailRepository.findByBlogId(source.id);
                    map.put("agdState", agd.state);
                }
                User user = userRepository.findOne(source.userId);
                map.put("nickName", user.nickName);
                map.put("photo", user.photo);
                map.put("urls", blogMediaRepository.findUrlByBlogId(source.id));
                return map;
            }

        }));
    }

    @Autowired
    private FeedbackRepository feedbackRepository;

    @ResponseBody
    @RequestMapping(path = "feedback/list", method = RequestMethod.GET)
    public AjaxResponse feedback_list(HttpServletRequest request, String token,
            HttpServletResponse response,
            @PageableDefault(sort = {"id"}, direction = Direction.DESC) Pageable pageable)
                    throws Exception {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getCurrentUser(token);
        Page<Feedback> page = feedbackRepository.findByState(LiveDieState.LIVE, pageable);
        return ajax.setObj(page.map(new Converter<Feedback, Map<String, Object>>() {
            @Override
            public Map<String, Object> convert(Feedback source) {
                Map<String, Object> map = MapUtils.convert(source);
                User user = userRepository.findOne(source.userId);
                map.put("nickName", user.nickName);
                map.put("photo", user.photo);
                return map;
            }

        }));
    }


    @ResponseBody
    @RequestMapping(path = "feedback/add", method = RequestMethod.POST)
    public AjaxResponse feedback_add(HttpServletRequest request, String token, String text,
            HttpServletResponse response,
            @PageableDefault(sort = {"id"}, direction = Direction.DESC) Pageable pageable)
                    throws Exception {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getCurrentUser(token);
        Feedback feedback = new Feedback();
        feedback.userId = su.id;
        feedback.text = text;
        feedbackRepository.save(feedback);
        return ajax;
    }
}
